using System;
using System.Collections;
using System.Text.RegularExpressions;

using DesignByContract;

namespace Outcoding.GraphGenerator.Entities {
    public class PointCollection : CollectionBase {

        #region Private Helper Classes (1)
        private class Constants
        {
            public const string DEFAULT_FONT_NAME = "Arial";
            public const int DEFAULT_FONT_SIZE = 10;
            public const bool DEFAULT_FONT_DECORATION_VALUE = false;
            public const string DEFAULT_FONT_COLOR = @"#000000";
        }
        #endregion

        /// <summary>
        /// Default Constructor
        /// </summary>
        public PointCollection(){
            mColor = Util.ColorTranslation(Constants.DEFAULT_FONT_COLOR);
        }

        /// <summary>
        /// This index into Point Collection.
        /// </summary>
        /// <param name="index">The index of the Point.</param>
        /// <returns>A Point object located in the given index.</returns>
        public Point this[int index]{
            get {
                return (Point)List[index];
            }
            set {
                List[index] = value;
            }
        }

        /// <summary>
        /// Add new Point to this collection.
        /// </summary>
        /// <param name="value">Point to add.</param>
        /// <returns>Index of the new value added.</returns>
        public int Add(Point value) {
            return List.Add(value);
        }

        /// <summary>
        /// Find the index for a given Point.
        /// </summary>
        /// <param name="value">Point to look for.</param>
        /// <returns>The index assign to the Point object.</returns>
        public int IndexOf(Point value) {
            return List.IndexOf(value);
        }

        /// <summary>
        /// Add new Point to this collection in the specified index.
        /// </summary>
        /// <param name="index">The index to place the Point.</param>
        /// <param name="value">The Point object to add.</param>
        public void Insert(int index, Point value) {
            List.Insert(index, value);
        }

        /// <summary>
        /// Remove a Point from this collection.
        /// </summary>
        /// <param name="value">Point object to remove.</param>
        public void Remove(Point value) {
            List.Remove(value);
        }

        /// <summary>
        /// Indicates if a Point exists in this collection.
        /// </summary>
        /// <param name="value">The Point to search.</param>
        /// <returns>A Boolean value indicating whether or not the Point exists in this collection.</returns>
        public bool Contains(Point value) {
            // If value is not of type Point, this will return false.
            return List.Contains(value);
        }

        /// <summary>
        /// Check Type on insert.
        /// </summary>
        protected override void OnInsert(int index, object value) {
            base.OnInsert(index, value);
            if (value.GetType() != typeof(Point))
                throw new ArgumentException("value must be of type Point", "value");
        }

        /// <summary>
        /// Check type on removal.
        /// </summary>
        protected override void OnRemove(int index, object value) {
            if (value.GetType() != typeof(Point))
                throw new ArgumentException("value must be of type Point.", "value");
        }

        /// <summary>
        /// Check type on set.
        /// </summary>
        protected override void OnSet(int index, object oldValue, object newValue) {
            if (newValue.GetType() != typeof(Point))
                throw new ArgumentException("newValue must be of type Point.", "newValue");
        }

        /// <summary>
        /// Check type on validate.
        /// </summary>
        protected override void OnValidate(object value) {
            if (value.GetType() != typeof(Point))
                throw new ArgumentException("value must be of type Point.");
        }

        private string mCurrencyString;

        public string CurrencyString
        {
            get { return mCurrencyString; }
            set
            {
                if (!String.IsNullOrEmpty(value))
                    mCurrencyString = value;
                else
                    mCurrencyString = String.Empty;
            }
        }

        private string mDecimalSpaces;

        public string DecimalSpaces
        {
            get { return mDecimalSpaces; }
            set
            {
                Regex regZeros = new Regex("0*");
                if (regZeros.IsMatch(value))
                    mDecimalSpaces = value;
                else
                    mDecimalSpaces = String.Empty;
            }
        }

        private bool mHasNegativePrefix;

        public bool HasNegativePrefix
        {
            get { return mHasNegativePrefix; }
            set { mHasNegativePrefix = value; }
        }

        private string mNegativePrefix = "-";

        public string NegativePrefix
        {
            get
            {
                if (mHasNegativePrefix)
                    return mNegativePrefix;
                else
                    return String.Empty;
            }
        }

        private bool mHasPercentSufix;

        public bool HasPercentSufix
        {
            get { return mHasPercentSufix; }
            set { mHasPercentSufix = value; }
        }

        private string mPercentSufix = "%";

        public string PercentSufix
        {
            get
            {
                if (HasPercentSufix)
                    return mPercentSufix;
                else
                    return String.Empty;
            }
        }

        private string mFontName = Constants.DEFAULT_FONT_NAME;

        private int mFontSize = Constants.DEFAULT_FONT_SIZE;

        private bool mIsFontBold = Constants.DEFAULT_FONT_DECORATION_VALUE;
        private bool mIsFontItalic = Constants.DEFAULT_FONT_DECORATION_VALUE;
        private bool mIsFontUnderline = Constants.DEFAULT_FONT_DECORATION_VALUE;

        public string FontName
        {
            get
            {
                return mFontName;
            }
            set
            {
                mFontName = value;
            }
        }

        public int FontSize
        {
            get
            {
                return mFontSize;
            }
            set
            {
                Check.Ensure(value > 0, "Size value cannot be less than zero.", new ArgumentOutOfRangeException());
                mFontSize = value;
            }
        }

        public bool IsFontBold
        {
            get
            {
                return mIsFontBold;
            }
            set
            {
                mIsFontBold = value;
            }
        }

        public bool IsFontItalic
        {
            get
            {
                return mIsFontItalic;
            }
            set
            {
                mIsFontItalic = value;
            }
        }

        public bool IsFontUnderline
        {
            get
            {
                return mIsFontUnderline;
            }
            set
            {
                mIsFontUnderline = value;
            }
        }

        private long mColor;

        public long Color{
            get { return mColor; }
            set { mColor = value; }
        }
    }
}